package factorytest.iflytek.com.einkiflytekfactorytest.agingtest;

import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.wifi.WifiManager;
import android.os.Message;
import android.os.PowerManager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import factorytest.iflytek.com.einkiflytekfactorytest.R;
import factorytest.iflytek.com.einkiflytekfactorytest.common.BatteryCurrentThresholdEnum;
import factorytest.iflytek.com.einkiflytekfactorytest.common.BatteryInfo;
import factorytest.iflytek.com.einkiflytekfactorytest.common.FTUtils;
import factorytest.iflytek.com.einkiflytekfactorytest.common.ForeLightCtrl;
import factorytest.iflytek.com.einkiflytekfactorytest.common.LedCtrl;
import factorytest.iflytek.com.einkiflytekfactorytest.config.EinkProperty;
import factorytest.iflytek.com.einkiflytekfactorytest.device.DeviceAttr;
import factorytest.iflytek.com.einkiflytekfactorytest.factorytestui.FactoryTestItemsEnum;
import factorytest.iflytek.com.einkiflytekfactorytest.myrecorder.IRecordListener;
import factorytest.iflytek.com.einkiflytekfactorytest.myrecorder.RecorderOperator;
import factorytest.iflytek.com.einkiflytekfactorytest.utils.DebugLog;
import factorytest.iflytek.com.einkiflytekfactorytest.utils.FileReadWrite;
import factorytest.iflytek.com.einkiflytekfactorytest.utils.SystemPropertyUtil;
import factorytest.iflytek.com.einkiflytekfactorytest.utils.TimeStringUtils;
import factorytest.iflytek.com.einkiflytekfactorytest.utils.UsefulUtils;

public class TestHardware extends AgingTestItemBase {

    private final boolean ENABLE_UPDATE_SCREEN = EinkProperty.isAgingScreen();

    private static final int MSG_TEST_SCREEN = 10;
    private static final int PERIOD_TEST_SCREEN = 5000;

    private static final int MSG_TOGGLE_WIFI = 20;
    private static final int PERIOD_TOGGLE_WIFI = 4000;

    private static final int MSG_TOGGLE_BT = 30;
    private static final int PERIOD_TOGGLE_BT = 4000;

    private static final int MSG_RECORD_START = 40;
    private static final int PERIOD_RECORD_START = 60 * 1000;

    private static final int MSG_RECORD_STOP = 41;
    private static final int PERIOD_RECORD_STOP = 10 * 1000;

    private static final int MSG_PLAY_SOUND_START = 50;

    private static final int MSG_CHECK_TEST_CPU = 60;
    private static final int PERIOD_CHECK_TEST_CPU = 1000 * 60 * 4;// 4min


    public TestHardware(@NonNull Context context, @NonNull View view) {
        super(context, view);
    }

    @Override
    protected void handleMessage(Message msg) {
        final int what = msg.what;
        switch (what) {
            case MSG_TEST_SCREEN:
                updateScreen();
                //更新 screen 的时候, 更新状态数据显示
                updateHardwareAgingInfo();
                break;
            case MSG_TOGGLE_WIFI:
                toggleWifiEnable();
                break;
            case MSG_TOGGLE_BT:
                toggleBluetoothEnable();
                break;
            case MSG_RECORD_START:
                startRecordTread();
                break;
            case MSG_RECORD_STOP:
                stopRecordThread();
                break;
            case MSG_PLAY_SOUND_START:
                doStartTestPlaySound();
                break;
            case MSG_CHECK_TEST_CPU:
                checkResultOfCpuTest();
                break;

        }
    }

    @Override
    protected void doStartTest() {

        DebugLog.e("TestHardware doStartTest");

        startTestScreen();

        startTestRecord();

        startTestBT();
        startTestWifi();

        startTestPlaySound();

        startBatteryInfo();

        startTestEmmc();

        startCpuTest();

        acquireWakeLock();
    }

    @Override
    protected void doStopTest() {
        DebugLog.e("TestHardware doStopTest");

        if (getLinearLayoutContainer() != null) {
            getLinearLayoutContainer().setBackgroundColor(Color.TRANSPARENT);
        }


        stopTestBT();
        stopTestWifi();

        stopTestScreen();

        stopTestPlaySound();

        stopBatteryInfo();

        stopTestRecord();

        stopTestEmmc();

        stopCpuTest();

        releaseWakeLock();
    }

    @Override
    public AgingTestItemAttr getAgingTestItemAttr() {
        return AgingTestItemAttr.hardware;
    }

    private boolean ledOn = false;

    private void updateHardwareAgingInfo() {

        String screenState = getContext().getString(R.string.aging_hardware_screen,
                AgingTestItemAttr.getHardwareScreenCount(getContext()));

        String playSoundState = "";
        if (mediaPlayer != null) {
            int duration = mediaPlayer.getDuration();
            int pos = mediaPlayer.getCurrentPosition();
            String durationStr = TimeStringUtils.makeTimeString(duration);
            String posStr = TimeStringUtils.makeTimeString(pos);

            int count = AgingTestItemAttr.getHardwarePlaySoundCount(getContext());
            playSoundState = getContext().getString(R.string.aging_hardware_play_sound, count, durationStr, posStr);

        }

        final long usedTime = AgingTestItemAttr.getAgingTimeTick_ms(getContext()) - getAgingTestItemAttr().getStartTime_ms(getContext());
        final String timeStr = TimeStringUtils.makeTimeString(usedTime);

        String hardwareAgingTimeString = getContext().getString(R.string.aging_hardware_time_used, timeStr);

        int recordCnt = AgingTestItemAttr.getHardwareRecordCount(getContext());
        String recordState = getContext().getString(R.string.aging_hardware_record, recordCnt);

        int ledCnt = AgingTestItemAttr.getHardwareLedCount(getContext());
        ledOn = !ledOn;
        if (ledOn) {
            ledCnt++;
            AgingTestItemAttr.setHardwareLedCount(getContext(), ledCnt);
        }
        LedCtrl.setLed(ledOn, LedCtrl.LedAttr.led_green);
        LedCtrl.setLed(!ledOn, LedCtrl.LedAttr.led_red);

        String ledState = getContext().getString(R.string.aging_hardware_led, ledCnt);

        if (DeviceAttr.getRunningDeviceAttr().hasForeLight()) {
            ForeLightCtrl.getForeLightCtrl().setColdLightBrightness(getContext(), ledOn ? ForeLightCtrl.MAX_BRIGHTNESS : 0);
            ForeLightCtrl.getForeLightCtrl().setWarmLightBrightness(getContext(), !ledOn ? ForeLightCtrl.MAX_BRIGHTNESS : 0);
        }

        int cpuTestCount = AgingTestItemAttr.getHardwareCpuTestCount(getContext());
        int cpuTestFailCount = AgingTestItemAttr.getHardwareCpuFailCount(getContext());

        String cpuState = getContext().getString(R.string.aging_hardware_cpu_test, cpuTestCount, cpuTestFailCount, EinkProperty.getResultCpuTest());

        String errorBootState = getContext().getString(R.string.aging_hardware_error_boot, EinkProperty.getErrorBootCount());

        String emmcState = getContext().getString(R.string.aging_hardware_emmc_test, AgingTestItemAttr.getHardwareEmmcCount(getContext()));

        String allInfo = screenState + playSoundState + recordState
                + mBTState + mWifiState + mBatteryState + ledState
                + cpuState + errorBootState + emmcState
                + hardwareAgingTimeString;

        updateTxtItemInfo(allInfo);

    }


    ////////////////////////
    // WakeLock
    ////////////////////////

    private PowerManager.WakeLock mWakeLock;

    private void acquireWakeLock() {
        if (mWakeLock == null) {
            PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
            if (pm == null) {
                return;
            }
            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
                    this.getClass().getCanonicalName());
            mWakeLock.acquire();

        }
    }

    private void releaseWakeLock() {
        if (mWakeLock != null) {
            mWakeLock.release();
            mWakeLock = null;
        }
    }


    ////////////////////////
    // test screen
    ////////////////////////

    private int[] colorResIds;

    private int screenViewChangedCount = 0;
    private final static int SCREEN_VIEW_CHANGE_MAX_COUNT = 4;

    private void startTestScreen() {

        //拿到颜色数组
        colorResIds = getContext().getResources().getIntArray(R.array.color_gray_level);

        getHandler().sendEmptyMessage(MSG_TEST_SCREEN);

    }

    private void stopTestScreen() {

        getHandler().removeMessages(MSG_TEST_SCREEN);

    }

    private void updateScreen() {

        if (ENABLE_UPDATE_SCREEN) {

            screenViewChangedCount++;
            if (screenViewChangedCount >= SCREEN_VIEW_CHANGE_MAX_COUNT) {
                screenViewChangedCount = 0;

                int screenTestCount = AgingTestItemAttr.getHardwareScreenCount(getContext());
                screenTestCount++;
                AgingTestItemAttr.setHardwareScreenCount(getContext(), screenTestCount);
            }

            setChildView((screenViewChangedCount & 0x1) != 0, (screenViewChangedCount & 0x2) != 0);

        }

        getHandler().sendEmptyMessageDelayed(MSG_TEST_SCREEN, PERIOD_TEST_SCREEN);

    }

    //动态加载多个view，数量为colorResIds数组中的数量
    private void setChildView(boolean colorRevert, boolean vertical) {

        if (getLinearLayoutContainer() == null) {
            return;
        }

        getLinearLayoutContainer().removeAllViews();

        getLinearLayoutContainer().setOrientation(vertical ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL);

        for (int i = 0; i < colorResIds.length; i++) {
            View view = new View(getContext());
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            lp.weight = 1;
            int color = colorResIds[i];
            if (colorRevert) {
                color = colorResIds[colorResIds.length - 1 - i];
            }
            view.setBackgroundColor(color);
            view.setClickable(false);
            getLinearLayoutContainer().addView(view, lp);
        }
    }

    ////////////////////
    // play sound
    ////////////////////
    private MediaPlayer mediaPlayer;

    private void startTestPlaySound() {
        getHandler().sendEmptyMessage(MSG_PLAY_SOUND_START);
    }

    private void stopTestPlaySound() {

        getHandler().removeMessages(MSG_PLAY_SOUND_START);

        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();//回收资源
            mediaPlayer = null;
        }
    }

    private void doStartTestPlaySound() {
        if (mediaPlayer != null) {
            stopTestPlaySound();
        }
        try {
            AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
            int maxVolume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
            am.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume * 2 / 3, 0);

//            mediaPlayer = MediaPlayer.create(getContext(), R.raw.music_qingzanggaoyuan);
            mediaPlayer = MediaPlayer.create(getContext(), R.raw.music_test_channel);
//            mediaPlayer.setLooping(true);//这种这个后, setOnCompletionListener 不能被调用了.
            mediaPlayer.start();

        } catch (Exception e) {
            DebugLog.e("exception e = " + e.getMessage());
        }

        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {

            @Override
            public void onCompletion(MediaPlayer mp) {
                int count = AgingTestItemAttr.getHardwarePlaySoundCount(getContext());
                count++;
                AgingTestItemAttr.setHardwarePlaySoundCount(getContext(), count);

                getHandler().sendEmptyMessage(MSG_PLAY_SOUND_START);
            }
        });

        mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                DebugLog.e("onError, what = " + what + ", extra = " + extra);
                return true;
            }
        });

    }

    ///////////////////////////
    // toggle wifi
    ///////////////////////////

    private String mWifiState = "";

    private void startTestWifi() {

        registerWifiStateChangedReceiver();

        getHandler().sendEmptyMessage(MSG_TOGGLE_WIFI);

    }

    private void stopTestWifi() {

        unregisterWifiStateChangedReceiver();

        getHandler().removeMessages(MSG_TOGGLE_WIFI);

    }

    private void toggleWifiEnable() {

        WifiManager wm = (WifiManager) getContext().getSystemService(WifiManager.class);
        if (wm == null) {
            return;
        }

        wm.setWifiEnabled(!wm.isWifiEnabled());

    }

    private void registerWifiStateChangedReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        getContext().registerReceiver(wifiStateChangedReceiver, filter);
    }

    private void unregisterWifiStateChangedReceiver() {
        getContext().unregisterReceiver(wifiStateChangedReceiver);
    }
    private void updateWifiString(String state) {

        int count = AgingTestItemAttr.getHardwareWifiOnOffCount(getContext());
        mWifiState = getContext().getString(R.string.aging_hardware_wifi_state, state, count);

    }

    private BroadcastReceiver wifiStateChangedReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (action == null) {
                return;
            }

            if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {//这个监听wifi的打开与关闭，与wifi的连接无关
                int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1);

                int resId = R.string.aging_hardware_status_unknown;

                switch (wifiState) {
                    case WifiManager.WIFI_STATE_DISABLED:
                        resId = R.string.aging_hardware_status_off;

                        getHandler().sendEmptyMessageDelayed(MSG_TOGGLE_WIFI, PERIOD_TOGGLE_WIFI);

                        break;
                    case WifiManager.WIFI_STATE_DISABLING:
                        resId = R.string.aging_hardware_status_turning_off;
                        break;
                    case WifiManager.WIFI_STATE_ENABLED:
                        resId = R.string.aging_hardware_status_on;
                        int count = AgingTestItemAttr.getHardwareWifiOnOffCount(context);
                        count++;
                        AgingTestItemAttr.setHardwareWifiOnOffCount(context, count);

                        getHandler().sendEmptyMessageDelayed(MSG_TOGGLE_WIFI, PERIOD_TOGGLE_WIFI);

                        break;
                    case WifiManager.WIFI_STATE_ENABLING:
                        resId = R.string.aging_hardware_status_turning_on;
                        break;
                    case WifiManager.WIFI_STATE_UNKNOWN:
                        DebugLog.i("wifiState:WIFI_STATE_UNKNOWN");
                        break;
                }

                updateWifiString(context.getString(resId));
            }
        }
    };

    ////////////////////////
    // toggle bt
    ////////////////////////

    private String mBTState = "";

    private void startTestBT() {

        registerBluetoothStateChangeReceiver();

        getHandler().sendEmptyMessage(MSG_TOGGLE_BT);

    }

    private void stopTestBT() {

        unregisterBluetoothStateChangeReceiver();

        getHandler().removeMessages(MSG_TOGGLE_BT);

    }

    private void toggleBluetoothEnable() {
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null) {
            DebugLog.e("BluetoothAdapter is null");
            return;
        }
        if (!bluetoothAdapter.isEnabled()) {
            bluetoothAdapter.enable();  //打开蓝牙，需要BLUETOOTH_ADMIN权限
        } else {
            bluetoothAdapter.disable();
        }

    }

    private void registerBluetoothStateChangeReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        getContext().registerReceiver(btStateChangedReceiver, filter);
    }

    private void unregisterBluetoothStateChangeReceiver() {
        getContext().unregisterReceiver(btStateChangedReceiver);
    }

    private void updateBTString(String state) {

        int count = AgingTestItemAttr.getHardwareBTOnOffCount(getContext());
        mBTState = getContext().getString(R.string.aging_hardware_bt_state, state, count);

    }

    private BroadcastReceiver btStateChangedReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (action == null) {
                return;
            }
            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
                        BluetoothAdapter.ERROR);
                int resId = R.string.aging_hardware_status_unknown;

                switch (state) {
                    case BluetoothAdapter.STATE_OFF:
                        resId = R.string.aging_hardware_status_off;

                        getHandler().sendEmptyMessageDelayed(MSG_TOGGLE_BT, PERIOD_TOGGLE_BT);

                        break;
                    case BluetoothAdapter.STATE_TURNING_OFF:
                        resId = R.string.aging_hardware_status_turning_off;
                        break;
                    case BluetoothAdapter.STATE_ON:
                        resId = R.string.aging_hardware_status_on;

                        int count = AgingTestItemAttr.getHardwareBTOnOffCount(context);
                        count++;
                        AgingTestItemAttr.setHardwareBTOnOffCount(context, count);

                        getHandler().sendEmptyMessageDelayed(MSG_TOGGLE_BT, PERIOD_TOGGLE_BT);

                        break;
                    case BluetoothAdapter.STATE_TURNING_ON:
                        resId = R.string.aging_hardware_status_turning_on;
                        break;
                }
                updateBTString(context.getString(resId));
            }
        }
    };

    ////////////
    // battery
    ////////////

    private BatteryInfo batteryInfo;
    private String mBatteryState = "";


    private void startBatteryInfo() {

        if (batteryInfo == null) {
            batteryInfo = new BatteryInfo(getContext());
        }
        batteryInfo.setOnBatteryChangedListener(onBatteryChangedListener);
        batteryInfo.startMonitor();

    }

    private void stopBatteryInfo() {

        if (batteryInfo == null) {
            return;
        }
        batteryInfo.stopMonitor();
        batteryInfo.setOnBatteryChangedListener(null);
    }

    private BatteryInfo.OnBatteryChangedListener onBatteryChangedListener
            = new BatteryInfo.OnBatteryChangedListener() {
        @Override
        public void onBatteryChangedListener(BatteryInfo info) {

            mBatteryState = getContext().getString(R.string.aging_hardware_battery_info,
                    info.getBatteryVoltage(),
                    info.getBatteryLevel(),
                    info.getBatteryStatusString(),
                    info.getBatteryCurrent_mA());

            BatteryCurrentThresholdEnum thresholdEnum = null;
            for (BatteryCurrentThresholdEnum e : BatteryCurrentThresholdEnum.values()) {
                if (e.isInRange(info.getBatteryLevel())) {
                    thresholdEnum = e;
                    break;
                }
            }

            String result = FactoryTestItemsEnum.battery.getResult(getContext());

            if (thresholdEnum != null && (info.getBatteryCurrent_mA() >= thresholdEnum.getCurrent())) {
                result = getContext().getString(R.string.test_result_pass);
                FactoryTestItemsEnum.battery.setResult(getContext(), result);
            }

            mBatteryState = getContext().getString(R.string.ft_aging_battery_info,
                    info.getBatteryVoltage(),
                    info.getBatteryLevel(),
                    info.getBatteryStatusString(),
                    info.getBatteryCurrent_mA(), result);

        }

    };

    //////////////////////////////////////////////////////////////////////////
    //test emmc

    private final static int MAX_COUNT_EMMC_TEST = 3;
    private final static int MAX_COUNT_EMMC_TEST_PRO = 2;

    private List<TestEmmcController.EmmcInfo> emmcTestWriteList = new ArrayList<>();
    private List<TestEmmcController.EmmcInfo> emmcTestReadList = new ArrayList<>();


    private void startTestEmmc() {
        TestEmmcController.getInstance().deleteTestFiles();
//        FileReadWrite.deleteFile(AgingTestItemAttr.PATH_TEST_EMMC_FAIL);

        doStartTestEmmc();
    }

    private void doStartTestEmmc() {

//        if (AgingTestItemAttr.getHardwareEmmcTestFailed(mContext)) {
//            DebugLog.e("Test emmc had failed, quit emmc test");
//            return;
//        }


        int count = AgingTestItemAttr.getHardwareEmmcCount(getContext());
        int maxCount = MAX_COUNT_EMMC_TEST;
        if (UsefulUtils.isIflytekProByCheckRom()) {
            maxCount = MAX_COUNT_EMMC_TEST_PRO;
        }

        if (count >= maxCount) {
            DebugLog.e("Test emmc count is " + count + ", No more emmc test");
            return;
        }

        for (TestEmmcController.EmmcInfo info : TestEmmcController.EmmcInfo.values()) {
            if (!emmcTestWriteList.contains(info)) {
                emmcTestWriteList.add(info);
            }
            if (!emmcTestReadList.contains(info)) {
                emmcTestReadList.add(info);
            }
        }

        DebugLog.e("Test emmc count is " + count + ", keep emmc test");

        TestEmmcController.getInstance().addOnWROverListener(onWROverListener);
        TestEmmcController.getInstance().setMarginSpace((count) * TestEmmcController.HALF_G);
        TestEmmcController.getInstance().setContext(getContext());
        TestEmmcController.getInstance().startTest();

    }

    private void stopTestEmmc() {

        DebugLog.e("stop test emmc");

        TestEmmcController.getInstance().removeOnWROverListener(onWROverListener);
        TestEmmcController.getInstance().stopTest();

    }


    private void checkTestEmmcAndTryStartAgain() {
        if (!(emmcTestReadList.isEmpty() && emmcTestWriteList.isEmpty())) {
            return;
        }

        // 完整的测了一次.
        int count = AgingTestItemAttr.getHardwareEmmcCount(getContext());
        count++;
        AgingTestItemAttr.setHardwareEmmcCount(getContext(), count);

        if (AgingTestItemAttr.isHardwareEmmcTestFailed(getContext())) {
            DebugLog.e("Test emmc failed, keep written file to check! Quit test emmc.");
            getAgingTestItemAttr().setForceTestOver(getContext(), true);
            return;
        }

        TestEmmcController.getInstance().stopTest();
        TestEmmcController.getInstance().deleteTestFiles();

        doStartTestEmmc();

    }

    private TestEmmcController.OnWROverListener onWROverListener =
            new TestEmmcController.OnWROverListener() {
                @Override
                public void onWriteOverListener(TestEmmcController.EmmcInfo info, long time_ms) {

                    emmcTestWriteList.remove(info);
                    checkTestEmmcAndTryStartAgain();
                }

                @Override
                public void onReadOverListener(TestEmmcController.EmmcInfo info, long time_ms) {

                    emmcTestReadList.remove(info);
                    checkTestEmmcAndTryStartAgain();

                }

                @Override
                public void onTestFailed(TestEmmcController.EmmcInfo info, String filePath, long offset, byte shouldValue, byte realValue) {

                    String log = "onTestFailed : info = " + info + ", filePath " + filePath
                            + ", offset = " + offset
                            + ", shouldValue =  0x" + Integer.toHexString((0xff & shouldValue))
                            + ", realValue = 0x" + Integer.toHexString((0xff & realValue))
                            + "\n";

                    DebugLog.e("EMMC error occurred, log path = " + AgingTestItemAttr.PATH_TEST_EMMC_HARDWARE_FAIL);

                    AgingTestItemAttr.setHardwareEmmcTestFailed(getContext(), true);

                    FileReadWrite.writeAppendFile(AgingTestItemAttr.PATH_TEST_EMMC_HARDWARE_FAIL, log);

                }
            };
    //////////////////////////////////////////////////////////////////////////

    //////////////////////////////////////////////////////////////////////////
    // cpu test

    private final static int MAX_COUNT_CPU_TEST = 1;


    private void startCpuTest() {

        EinkProperty.clearCpuTestResult();
        EinkProperty.clearErrorBootCount();
        doStartCpuTest();
    }

    private void doStartCpuTest() {
        EinkProperty.startOrStopCpuTest(true);

        getHandler().removeMessages(MSG_CHECK_TEST_CPU);
        getHandler().sendEmptyMessageDelayed(MSG_CHECK_TEST_CPU, PERIOD_CHECK_TEST_CPU);

    }

    private void checkResultOfCpuTest() {

        EinkProperty.CpuTestResultAttr attr = EinkProperty.getCpuTestResultAttr();
        DebugLog.e("songshitian checkResultOfCpuTest attr = " + attr);

        switch (attr) {
            case ok:
                int count = AgingTestItemAttr.getHardwareCpuTestCount(getContext());
                count++;
                AgingTestItemAttr.setHardwareCpuTestCount(getContext(), count);

                DebugLog.e("songshitian checkResultOfCpuTest ok, count = " + count);
                if (count >= MAX_COUNT_CPU_TEST) {
                    break;
                }

                doStartCpuTest();
                break;
            case fail:
                int failCount = AgingTestItemAttr.getHardwareCpuFailCount(getContext());
                failCount++;
                AgingTestItemAttr.setHardwareCpuFailCount(getContext(), failCount);

                DebugLog.e("songshitian checkResultOfCpuTest failed, count = " + failCount);
                if (failCount >= MAX_COUNT_CPU_TEST) {
                    break;
                }

                doStartCpuTest();

                break;
            default:
                getHandler().sendEmptyMessageDelayed(MSG_CHECK_TEST_CPU, PERIOD_CHECK_TEST_CPU);
                break;
        }
    }

    private void stopCpuTest() {
        getHandler().removeMessages(MSG_CHECK_TEST_CPU);
        EinkProperty.startOrStopCpuTest(false);

    }

    //////////////////////
    //    Recorder
    /////////////////////
    private RecorderThread recorderThread;

    /**
     * 要有 record 授权. 对于我们的测试的墨水屏, 他已经授权了
     */
    public void startTestRecord() {
        getHandler().removeMessages(MSG_RECORD_STOP);
        getHandler().sendEmptyMessage(MSG_RECORD_START);
    }

    private void stopTestRecord() {
        stopRecordThread();

        getHandler().removeMessages(MSG_RECORD_STOP);
        getHandler().removeMessages(MSG_RECORD_START);
    }

    private void startRecordTread() {

        if (recorderThread != null) {
            stopRecordThread();
        }

        int count = AgingTestItemAttr.getHardwareRecordCount(getContext());
        count++;
        AgingTestItemAttr.setHardwareRecordCount(getContext(), count);

        recorderThread = new RecorderThread("aging_rec-" + count, null);
        recorderThread.start();

        getHandler().sendEmptyMessageDelayed(MSG_RECORD_STOP, PERIOD_RECORD_STOP);
    }

    private void stopRecordThread() {

        if (recorderThread != null) {
            recorderThread.joinThread();
            recorderThread = null;
        }

        getHandler().sendEmptyMessageDelayed(MSG_RECORD_START, PERIOD_RECORD_START);

    }

    private class RecorderThread extends Thread {

        private final String RECORDER_FILE_PATH = FTUtils.getFTStorageDirectory() + File.separator + "aging_recorder.pcm";


        private RecorderOperator recorderOperator;

        public RecorderThread(String name, IRecordListener listener) {
            super(name);

            recorderOperator = RecorderOperator.getInstance();
            recorderOperator.setRecordingListener(listener);
            recorderOperator.setRecordPath(RECORDER_FILE_PATH);

            if (EinkProperty.getIflytekBoardVersion() == 3) {
                recorderOperator.setChannelConfig(AudioFormat.CHANNEL_IN_STEREO);
                recorderOperator.setAudioFormat(AudioFormat.ENCODING_PCM_FLOAT);
            }

        }

        @Override
        public void run() {
            if (recorderOperator == null) {
                return;
            }

            recorderOperator.startRecord();

        }

        public void joinThread() {

            if (recorderOperator != null) {
                recorderOperator.stopRecord();
            }

            while (isAlive()) {
                try {
                    join(2500);
                } catch (InterruptedException e) {
                    // Ignore.
                }
            }
        }
    }
}
